Recipe for getting local constraints#1014
Conversation
|
Everything seems fine, will merge in a couple days, if everyone's alright with it. |
|
Better iterate through the constraint handlers and get the active constraints using https://scipopt.org/doc-9.2.2/html/group__PublicConshdlrMethods.php#gae573c332a19e69c45163fadfeab3948b and https://scipopt.org/doc-9.2.2/html/group__PublicConshdlrMethods.php#gad610bfb6d34ee998835d8b9bbbb9cf8c and exclude original ones manually. |
|
Why is it better? You mean that some constraints are discarded for whatever reason, but they would appear here? |
|
It should also be checked that the constraints are enabled, but I rather wonder about the performance impact of walking back to the root for each node. If local constraints are added for every node, this might be okay though. However, I am not sure about the usecase of this set of constraints. |
|
@DominikKamp mostly for debugging. But it seems useful to be able to get the constraints you added after starting to solve. Especially since users don't have an easy way to get the constraints that make up the local problem. I guess interfacing Regarding performance, it doesn't seem that bad, plus it's a recipe. |
|
But global constraints are also local constraints so the method name is actually misleading. |
|
What would you name it? I can also return all the local constraints (including original ones), but if users are interested in the non-original ones, they would need to dig through the array. One option would actually be to return a two-dimensional array instead. First entry with original constraints, second entry with non-original constraints. |
|
Since you prepend the added constraints, you could also just include the root constraints and additionally provide their number, or even better return an array with all the lengths. |
|
See how you like it now, @DominikKamp. It might be better if we just return EDIT: but then retrieving the constraints is very annoying, would need plenty of indices. I'm happy with this for now, since it's a recipe no need for perfection. |
|
Actually I meant just two lists, one for all enabled constraints added on the whole path in sequence, another one with the number of constraints for each node on the path. Note, that all constraints disabled in the current node need to be excluded manually. Furthermore, you might want to skip the nodes before the effective root. |
|
If we're going to discriminate the number of constraints by node, then I'd favor a dictionary with node numbers as keys, otherwise, it seems like a mess. The constraints are disabled, but still valid, no? Why would it matter if they're there or not? I'd rather have them, and then people check if they're active manually, otherwise it seems like they disappeared. The effective root is a term I'm not familiar with, what do you mean? In theory, we could just check between nodes A and its ancestor B, but I'm assuming that B is always the actual root. |
|
Fine with a dictionary for the numbers of constraints (though it might make it more difficult to access the number of global constraints). Disabled constraints are technically not part of the local description but should be valid, just thought that it is the purpose of this function to provide the current set of local constraints. By default, if all but one child of the current effective root is cut off, the single remaining child becomes the next effective root and all its bound and constraint set changes are globalized, but you actually need to go to the original root to get all global constraints. |
|
After digesting a bit, I'm fine with the way it is now. The purpose is to facilitate debugging, and it's also a recipe. If any users end up using it and have suggestions, please feel free to share. Thanks for the input, Dominik! |
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a recipe for retrieving local constraints from SCIP nodes. The main purpose is to provide a convenient way to access all constraints that are valid in the current focus node, excluding the original global constraints.
Key Changes:
- Adds a new recipe module
getLocalConss.pywith functions to retrieve local constraints and their counts - Includes comprehensive test coverage for the new functionality
- Adds a
writeMIPmethod to output MIP relaxations
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/pyscipopt/recipes/getLocalConss.py |
New recipe module implementing the core functionality for retrieving local constraints |
tests/test_recipe_getLocalConss.py |
Test file validating the local constraints recipe functionality |
src/pyscipopt/scip.pxi |
Added writeMIP method for outputting MIP relaxations |
src/pyscipopt/scip.pxd |
Added function declaration for SCIPwriteMIP |
src/pyscipopt/recipes/nonlinear.py |
Removed extraneous blank line |
CHANGELOG.md |
Updated changelog with new recipe addition |
|
|
||
| return [model.getConss(), added_conss] | ||
|
|
||
| def getNLocalConss(model: Model, node = None) -> list[int]: |
There was a problem hiding this comment.
The return type annotation should be -> tuple[int, int] or -> list[int] to be more precise, but the current annotation is consistent with the actual return behavior.
| def getNLocalConss(model: Model, node = None) -> list[int]: | |
| def getNLocalConss(model: Model, node = None) -> tuple[int, int]: |
SCIP only allows one to get the constraints added to a given node. It is now possible to get all constraints valid in the focus node, excluding the original ones. Maybe we can also add a
getLocalConsNode, or even an optional argument defaulting to the current node.